"""
债券对比分析智能体

基于LangGraph ReAct模式，对比分析多个债券的各项指标。
"""

from typing import Dict, Any, List, Optional
from langchain_core.tools import Tool
import pandas as pd

from agents import BondAnalysisAgent, LLMConfig
from tools.bond_data_provider import bond_data_provider


class BondComparisonAgent(BondAnalysisAgent):
    """债券对比分析智能体"""
    
    def __init__(self, llm_config: Optional[LLMConfig] = None):
        super().__init__(
            name="bond_comparison",
            description="对比分析多个债券的各项指标",
            llm_config=llm_config
        )
        
        self.analysis_dimensions = ["comparison", "multi_bond"]
    
    def get_tools(self) -> List[Tool]:
        """获取债券对比分析所需的工具"""
        
        async def get_multiple_bonds_info(bond_codes: str) -> str:
            """获取多个债券的基本信息（债券代码用逗号分隔）"""
            try:
                # 解析债券代码
                codes = [code.strip() for code in bond_codes.split(',')]
                
                if len(codes) < 2:
                    return "请提供至少2个债券代码进行对比，用逗号分隔"
                
                if len(codes) > 5:
                    return "最多支持对比5个债券，请减少债券数量"
                
                result = "=== 债券基本信息对比 ===\n\n"
                
                bonds_data = []
                
                for code in codes:
                    info = await bond_data_provider.get_bond_basic_info(code)
                    if info:
                        bonds_data.append(info)
                        result += f"【{code} - {info.get('债券简称', 'N/A')}】\n"
                        result += f"发行人: {info.get('正股名称', 'N/A')}\n"
                        result += f"最新价: {info.get('最新价', 'N/A')}元\n"
                        result += f"涨跌幅: {info.get('涨跌幅', 'N/A')}%\n"
                        result += f"债券评级: {info.get('债券评级', 'N/A')}\n"
                        result += f"发行规模: {info.get('发行规模', 'N/A')}亿元\n"
                        result += f"到期时间: {info.get('到期时间', 'N/A')}\n"
                        result += "\n"
                    else:
                        result += f"⚠️ 未找到债券 {code} 的信息\n\n"
                
                if len(bonds_data) < 2:
                    return "有效债券数量不足2个，无法进行对比"
                
                result += f"\n成功获取 {len(bonds_data)} 个债券的信息\n"
                
                return result
            except Exception as e:
                return f"获取多个债券信息失败: {str(e)}"
        
        async def compare_valuation_metrics(bond_codes: str) -> str:
            """对比债券估值指标（债券代码用逗号分隔）"""
            try:
                codes = [code.strip() for code in bond_codes.split(',')]
                
                result = "=== 估值指标对比 ===\n\n"
                
                # 创建对比表格数据
                comparison_data = []
                
                for code in codes:
                    detail = await bond_data_provider.get_bond_detail(code)
                    if not detail.empty:
                        row = detail.iloc[0]
                        comparison_data.append({
                            '债券代码': code,
                            '债券简称': row.get('债券简称', 'N/A'),
                            '最新价': row.get('最新价', 'N/A'),
                            '转股价值': row.get('转股价值', 'N/A'),
                            '转股溢价率': row.get('转股溢价率', 'N/A'),
                            '纯债价值': row.get('纯债价值', 'N/A'),
                            '纯债溢价率': row.get('纯债溢价率', 'N/A'),
                            '到期收益率': row.get('到期收益率', 'N/A'),
                        })
                
                if not comparison_data:
                    return "未获取到有效的估值数据"
                
                # 输出对比表格
                result += "【估值指标对比表】\n"
                result += f"{'债券代码':<10} {'债券简称':<12} {'价格':<8} {'转股溢价率':<10} {'到期收益率':<10}\n"
                result += "-" * 70 + "\n"
                
                for data in comparison_data:
                    result += f"{data['债券代码']:<10} "
                    result += f"{str(data['债券简称']):<12} "
                    result += f"{str(data['最新价']):<8} "
                    result += f"{str(data['转股溢价率']):<10} "
                    result += f"{str(data['到期收益率']):<10}\n"
                
                result += "\n"
                
                # 分析对比结果
                result += "【估值分析】\n"
                
                # 找出最低转股溢价率
                valid_premiums = [(d['债券代码'], d['转股溢价率']) 
                                 for d in comparison_data 
                                 if isinstance(d['转股溢价率'], (int, float))]
                
                if valid_premiums:
                    min_premium = min(valid_premiums, key=lambda x: x[1])
                    result += f"✓ 转股溢价率最低: {min_premium[0]} ({min_premium[1]}%)\n"
                
                # 找出最高到期收益率
                valid_ytm = [(d['债券代码'], d['到期收益率']) 
                            for d in comparison_data 
                            if isinstance(d['到期收益率'], (int, float))]
                
                if valid_ytm:
                    max_ytm = max(valid_ytm, key=lambda x: x[1])
                    result += f"✓ 到期收益率最高: {max_ytm[0]} ({max_ytm[1]}%)\n"
                
                # 计算双低值
                result += "\n【双低值对比】\n"
                for data in comparison_data:
                    price = data['最新价']
                    premium = data['转股溢价率']
                    if isinstance(price, (int, float)) and isinstance(premium, (int, float)):
                        double_low = price + premium
                        result += f"{data['债券代码']}: {double_low:.2f}\n"
                
                return result
            except Exception as e:
                return f"对比估值指标失败: {str(e)}"
        
        async def compare_credit_ratings(bond_codes: str) -> str:
            """对比债券信用评级（债券代码用逗号分隔）"""
            try:
                codes = [code.strip() for code in bond_codes.split(',')]
                
                result = "=== 信用评级对比 ===\n\n"
                
                rating_data = []
                
                for code in codes:
                    detail = await bond_data_provider.get_bond_detail(code)
                    if not detail.empty:
                        row = detail.iloc[0]
                        rating_data.append({
                            '债券代码': code,
                            '债券简称': row.get('债券简称', 'N/A'),
                            '债券评级': row.get('债券评级', 'N/A'),
                            '发行规模': row.get('发行规模', 'N/A'),
                            '剩余规模': row.get('剩余规模', 'N/A'),
                        })
                
                if not rating_data:
                    return "未获取到评级数据"
                
                # 输出对比表格
                result += "【评级对比表】\n"
                result += f"{'债券代码':<10} {'债券简称':<12} {'评级':<8} {'发行规模':<10} {'剩余规模':<10}\n"
                result += "-" * 70 + "\n"
                
                for data in rating_data:
                    result += f"{data['债券代码']:<10} "
                    result += f"{str(data['债券简称']):<12} "
                    result += f"{str(data['债券评级']):<8} "
                    result += f"{str(data['发行规模']):<10} "
                    result += f"{str(data['剩余规模']):<10}\n"
                
                result += "\n"
                
                # 评级分析
                result += "【评级分析】\n"
                
                # 评级排序（简化版）
                rating_order = ['AAA', 'AA+', 'AA', 'AA-', 'A+', 'A', 'A-']
                
                for data in rating_data:
                    rating = data['债券评级']
                    if rating in rating_order:
                        level = rating_order.index(rating)
                        if level <= 1:
                            result += f"✓ {data['债券代码']}: {rating} - 优质评级\n"
                        elif level <= 3:
                            result += f"  {data['债券代码']}: {rating} - 良好评级\n"
                        else:
                            result += f"⚠️ {data['债券代码']}: {rating} - 一般评级\n"
                    else:
                        result += f"  {data['债券代码']}: {rating} - 评级信息不足\n"
                
                return result
            except Exception as e:
                return f"对比信用评级失败: {str(e)}"
        
        async def compare_liquidity(bond_codes: str) -> str:
            """对比债券流动性（债券代码用逗号分隔）"""
            try:
                codes = [code.strip() for code in bond_codes.split(',')]
                
                result = "=== 流动性对比 ===\n\n"
                
                liquidity_data = []
                
                for code in codes:
                    info = await bond_data_provider.get_bond_basic_info(code)
                    if info:
                        liquidity_data.append({
                            '债券代码': code,
                            '债券简称': info.get('债券简称', 'N/A'),
                            '成交量': info.get('成交量', 0),
                            '成交额': info.get('成交额', 0),
                            '剩余规模': info.get('剩余规模', 0),
                        })
                
                if not liquidity_data:
                    return "未获取到流动性数据"
                
                # 输出对比表格
                result += "【流动性对比表】\n"
                result += f"{'债券代码':<10} {'债券简称':<12} {'成交量(手)':<12} {'成交额(万)':<12} {'剩余规模(亿)':<12}\n"
                result += "-" * 70 + "\n"
                
                for data in liquidity_data:
                    result += f"{data['债券代码']:<10} "
                    result += f"{str(data['债券简称']):<12} "
                    result += f"{data['成交量']:<12} "
                    result += f"{data['成交额']:<12.2f} "
                    result += f"{data['剩余规模']:<12}\n"
                
                result += "\n"
                
                # 流动性分析
                result += "【流动性分析】\n"
                
                # 找出流动性最好的
                max_turnover = max(liquidity_data, key=lambda x: x['成交额'])
                result += f"✓ 流动性最好: {max_turnover['债券代码']} "
                result += f"(成交额: {max_turnover['成交额']:.2f}万元)\n"
                
                # 流动性评估
                for data in liquidity_data:
                    turnover = data['成交额']
                    if turnover > 1000:
                        result += f"✓ {data['债券代码']}: 流动性良好\n"
                    elif turnover > 100:
                        result += f"  {data['债券代码']}: 流动性一般\n"
                    else:
                        result += f"⚠️ {data['债券代码']}: 流动性较差\n"
                
                return result
            except Exception as e:
                return f"对比流动性失败: {str(e)}"
        
        async def generate_comparison_summary(bond_codes: str) -> str:
            """生成债券对比总结报告（债券代码用逗号分隔）"""
            try:
                codes = [code.strip() for code in bond_codes.split(',')]
                
                result = "=== 债券对比总结报告 ===\n\n"
                
                # 收集所有数据
                bonds_summary = []
                
                for code in codes:
                    info = await bond_data_provider.get_bond_basic_info(code)
                    detail = await bond_data_provider.get_bond_detail(code)
                    
                    if info and not detail.empty:
                        row = detail.iloc[0]
                        
                        # 计算综合评分（简化版）
                        score = 0
                        
                        # 评级评分
                        rating = row.get('债券评级', '')
                        if rating in ['AAA', 'AA+']:
                            score += 30
                        elif rating in ['AA', 'AA-']:
                            score += 20
                        else:
                            score += 10
                        
                        # 收益率评分
                        ytm = row.get('到期收益率', 0)
                        if isinstance(ytm, (int, float)):
                            if ytm > 5:
                                score += 30
                            elif ytm > 2:
                                score += 20
                            else:
                                score += 10
                        
                        # 溢价率评分
                        premium = row.get('转股溢价率', 0)
                        if isinstance(premium, (int, float)):
                            if premium < 10:
                                score += 25
                            elif premium < 30:
                                score += 15
                            else:
                                score += 5
                        
                        # 流动性评分
                        turnover = info.get('成交额', 0)
                        if turnover > 1000:
                            score += 15
                        elif turnover > 100:
                            score += 10
                        else:
                            score += 5
                        
                        bonds_summary.append({
                            '债券代码': code,
                            '债券简称': info.get('债券简称', 'N/A'),
                            '评级': rating,
                            '到期收益率': ytm,
                            '转股溢价率': premium,
                            '综合评分': score
                        })
                
                if not bonds_summary:
                    return "未能生成对比总结"
                
                # 按综合评分排序
                bonds_summary.sort(key=lambda x: x['综合评分'], reverse=True)
                
                result += "【综合评分排名】\n"
                result += f"{'排名':<6} {'债券代码':<10} {'债券简称':<12} {'评级':<8} {'收益率':<10} {'溢价率':<10} {'评分':<8}\n"
                result += "-" * 80 + "\n"
                
                for idx, data in enumerate(bonds_summary, 1):
                    result += f"{idx:<6} "
                    result += f"{data['债券代码']:<10} "
                    result += f"{str(data['债券简称']):<12} "
                    result += f"{str(data['评级']):<8} "
                    result += f"{str(data['到期收益率']):<10} "
                    result += f"{str(data['转股溢价率']):<10} "
                    result += f"{data['综合评分']:<8}\n"
                
                result += "\n"
                
                # 推荐结论
                result += "【投资建议】\n"
                if bonds_summary:
                    best_bond = bonds_summary[0]
                    result += f"✓ 综合表现最优: {best_bond['债券代码']} - {best_bond['债券简称']}\n"
                    result += f"  评分: {best_bond['综合评分']}/100分\n"
                    result += f"  主要优势: "
                    
                    advantages = []
                    if best_bond['评级'] in ['AAA', 'AA+']:
                        advantages.append("优质评级")
                    if isinstance(best_bond['到期收益率'], (int, float)) and best_bond['到期收益率'] > 3:
                        advantages.append("较高收益率")
                    if isinstance(best_bond['转股溢价率'], (int, float)) and best_bond['转股溢价率'] < 20:
                        advantages.append("较低溢价率")
                    
                    result += "、".join(advantages) if advantages else "综合指标均衡"
                
                return result
            except Exception as e:
                return f"生成对比总结失败: {str(e)}"
        
        # 创建工具列表
        tools = [
            Tool(
                name="get_multiple_bonds_info",
                description="获取多个债券的基本信息，用于初步对比。参数为债券代码，用逗号分隔，例如：'123456,123457,123458'",
                func=lambda bond_codes: None,
                coroutine=get_multiple_bonds_info,
            ),
            Tool(
                name="compare_valuation_metrics",
                description="对比多个债券的估值指标，包括价格、溢价率、收益率等。参数为债券代码，用逗号分隔",
                func=lambda bond_codes: None,
                coroutine=compare_valuation_metrics,
            ),
            Tool(
                name="compare_credit_ratings",
                description="对比多个债券的信用评级和发行规模。参数为债券代码，用逗号分隔",
                func=lambda bond_codes: None,
                coroutine=compare_credit_ratings,
            ),
            Tool(
                name="compare_liquidity",
                description="对比多个债券的流动性指标。参数为债券代码，用逗号分隔",
                func=lambda bond_codes: None,
                coroutine=compare_liquidity,
            ),
            Tool(
                name="generate_comparison_summary",
                description="生成多个债券的综合对比总结报告，包括评分和投资建议。参数为债券代码，用逗号分隔",
                func=lambda bond_codes: None,
                coroutine=generate_comparison_summary,
            ),
        ]
        
        return tools
    
    def get_system_prompt(self) -> str:
        """获取系统提示词"""
        return """你是一个专业的债券对比分析专家，负责对比分析多个债券的各项指标。

你的分析流程：
1. 使用 get_multiple_bonds_info 获取多个债券的基本信息
2. 使用 compare_valuation_metrics 对比估值指标
3. 使用 compare_credit_ratings 对比信用评级
4. 使用 compare_liquidity 对比流动性
5. 使用 generate_comparison_summary 生成综合对比总结

重要提示：
- 所有工具的参数都是债券代码字符串，多个代码用逗号分隔
- 例如：'123456,123457,123458'
- 最多支持对比5个债券

分析要点：
- 从多个维度对比债券：估值、评级、流动性
- 识别每个债券的优势和劣势
- 基于对比结果给出投资建议
- 考虑投资者的风险偏好

请逐步使用工具获取信息，展示你的对比分析过程，最后给出：
1. 各债券的主要特点
2. 横向对比结论
3. 综合投资建议
"""


# 全局实例
bond_comparison_agent = BondComparisonAgent()